createTx: function(utxos, outs, fee) {
      /**
       * 构建转账数据
       *
       * @utxos
       * @outs  目标地址
       * @fee  手续费
       *
       *
       * 转账的步骤：
       * 1.根据需要转出到的地址和金额，构建outputs
       * 2.根据outputs总额，构建inputs，判断总额是否足够
       * 3.称重，然后根据费率计算手续费
       * 4.得到手续费后，校验inputs是否满足交易所需（inputs >= outputs + fee）
       * 4.1不满足需求则从utxos中取余额出来再次添加到inputs中，然后循环3,4
       * 5.计算是否需要找零（inputs > outputs + fee）
       * 5.1需要找零则在outputs中增加找零地址,由于地址增加，则需要重新执行3,4,5
       * 6.得到最后的交易数据
       * tips:
       * 1.注意BTC个数和聪(Sat)之间的转换
       * 2.utxos建议根据value升序排列
       *
       * @memberof BlockchainTool
       */
      if (!isArray(utxos) || isEmpty(utxos) || !isArray(outs) || isEmpty(outs) || !fee)
        return false
      const inputs = [],
        outputs = []
      let inputAmounts = 0,
        outAmounts = 0
      utxos = sortBy(utxos, 'value')
      const buildOutputs = () => {
        for (let i = 0; i < outs.length; i++) {
          /*构建outputs*/
          let amount = AbcUtils.btc.toSat(outs[i].amount)
          outputs.push({
            address: outs[i].address,
            amount,
            script_type: 'PAYTOADDRESS'
          })
          /*统计总量*/
          outAmounts = BN(outAmounts).plus(amount)
        }
      }
      const weigh = () => {
        /*称重*/
        const sizeIn = BN(inputs.length).times(148)
        const sizeOut = BN(outputs.length).times(34)
        const fees = BN(sizeIn)
          .plus(sizeOut)
          .plus(10)
          .times(fee)
        const total = BN(outAmounts).plus(fees)
        return AbcUtils.btc.toSat(total)
      }
      const createAddressN = path => {
        /*通过path构建addressN*/
        const addressN = []
        path = path.match(/\/[0-9]+('|H)?/g)
        for (let item of path) {
          let id = parseInt(item.match(/[0-9]+/g)[0])
          if (item.match(/('|H)/g)) id = (id | 0x80000000) >>> 0
          addressN.push(id)
        }
        return addressN
      }
      const buildInputs = () => {
        for (let i = 0; i < utxos.length; i++) {
          if (BN(inputAmounts).gte(weigh())) break
          const address_n = createAddressN(utxos[i].path)
          const amount = utxos[i].value
          const prev_hash = utxos[i].txid
          const prev_index = utxos[i].n
          const script_type = 'SPENDP2SHWITNESS'
          const sequence = 4294967295
          inputAmounts = BN(inputAmounts).plus(utxos[i].value)
          inputs.push({
            address_n,
            amount,
            prev_hash,
            prev_index,
            script_type,
            sequence
          })
        }
      }
      buildOutputs()
      buildInputs()
      /*余额不足*/
      if (BN(outAmounts).gt(inputAmounts)) return false
      const countChange = () => {
        /*计算找零*/
        let changeAmounts = BN(inputAmounts)
          .minus(outAmounts)
          .toNumber()
        if (changeAmounts > 0) {
          const address_n = [
            (this.purpose | 0x80000000) >>> 0,
            (this.coin | 0x80000000) >>> 0,
            (this.account | 0x80000000) >>> 0,
            1,
            0
          ]
          const amount = changeAmounts
          const script_type = 'PAYTOADDRESS'
          outputs.push({
            address_n,
            amount,
            script_type
          })
          /*outputs变化，重新称重,并构建inputs*/
          buildInputs()
        }
      }
      countChange()
      return {
        inputs: JSON.stringify(inputs, null, 4),
        outputs: JSON.stringify(outputs, null, 4)
      }
    },